package com.yoyosys.db.partition.query.impl;

import cn.hutool.core.convert.Convert;
import com.yoyosys.db.partition.query.PartitionQuery;
import com.yoyosys.db.partition.vo.Partition;
import com.yoyosys.db.partition.vo.PartitionInfo;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

/**
 * 达梦 分区分桶信息查询器
 */
public class DaMengPartitionQuery implements PartitionQuery {
    private static DaMengPartitionQuery instance = new DaMengPartitionQuery();
    private DaMengPartitionQuery(){}
    public static DaMengPartitionQuery getInstance(){
        return instance;
    }

    /**
     * 查询表分区信息
     *
     * @param conn
     * @param schemaName 库名
     * @param tableName
     * @return
     */
    @Override
    public PartitionInfo getPartition(Connection conn, String schemaName, String tableName) throws SQLException {
        PartitionInfo info = new PartitionInfo();
        info.setSchemaName(schemaName);
        info.setTableName(tableName);
        info.setPartitions(new ArrayList<>());

        // 获取分区类型和键
        String partitionTypeSql = new StringBuilder()
                .append(" SELECT  ")
                .append("     t.PARTITIONING_TYPE AS PARTITION_TYPE, ")
                .append("     (SELECT LISTAGG(c.COLUMN_NAME, ',') WITHIN GROUP (ORDER BY c.COLUMN_POSITION) ")
                .append("      FROM ALL_PART_KEY_COLUMNS c ")
                .append("      WHERE c.NAME = t.TABLE_NAME AND c.OWNER = t.OWNER) AS PARTITION_KEYS ")
                .append(" FROM  ALL_PART_TABLES t ")
                .append(" WHERE 1=1 ")
                .append("     AND t.OWNER = ? ")
                .append("     ANd t.TABLE_NAME = ? ")
                .toString();
        System.out.println("partitionTypeSql: " + partitionTypeSql);
        try (PreparedStatement pstmt = conn.prepareStatement(partitionTypeSql)) {
            pstmt.setString(1, schemaName);
            pstmt.setString(2, tableName);
            try (ResultSet rs = pstmt.executeQuery()) {
                if (rs.next()) {
                    info.setPartitionType(rs.getString("PARTITION_TYPE"));
                    info.setPartitionKey(rs.getString("PARTITION_KEYS"));
                }
            }
        }

        // 获取所有分区
        String partitionsSql = new StringBuilder()
                .append("SELECT PARTITION_NAME, HIGH_VALUE, TABLESPACE_NAME, NUM_ROWS ")
                .append("FROM ALL_TAB_PARTITIONS ")
                .append("WHERE TABLE_OWNER = ? AND TABLE_NAME = ? ")
                .append("ORDER BY PARTITION_POSITION")
                .toString();
        System.out.println("partitionsSql: " + partitionsSql);
        try (PreparedStatement pstmt = conn.prepareStatement(partitionsSql)) {
            pstmt.setString(1, schemaName);
            pstmt.setString(2, tableName);
            try (ResultSet rs = pstmt.executeQuery()) {
                while (rs.next()) {
                    Partition partition = new Partition();
                    partition.setName(rs.getString("PARTITION_NAME"));
                    partition.setExpression(rs.getString("HIGH_VALUE"));
                    partition.setStorageLocation(rs.getString("TABLESPACE_NAME"));
                    //达梦数据库默认不会自动收集分区表的行数统计信息,NUM_ROWS 字段需要手动收集统计信息后才会填充
                    //手工收集： DBMS_STATS.GATHER_TABLE_STATS(schemaName, tableName);
                    partition.setRowCount(Convert.toLong(rs.getLong("NUM_ROWS"), 0L));
                    info.getPartitions().add(partition);
                }
            }
        }

        return info;
    }

}
